import { is } from "ramda";
import * as tmp from "tmp";
import { FileResult } from "tmp";
import fs from "node:fs";
import { randomUUID } from "node:crypto";
import * as CryptoJS from "crypto-js";
import dayjs from "dayjs";
import { randomStr } from "./cmm.util";

/**
 * 创建时间戳文件名
 * @param prefix 前缀
 * @param ext 后缀
 */
export const createTimestampFilename = (prefix: string, ext: string) => {
  return `${prefix}_${dayjs().format("YYYYMMDDHHmmss")}_${randomStr(6)}.${ext}`;
};

/**
 * 随机生成文件名
 * @param ext 后缀
 * @param name 文件名称，如果不传，则随机生成
 */
export const createRandomFilename = (ext: string = "json", name?: string) => {
  return (name || randomUUID()) + `.${ext}`;
};

/**
 * 创建临时文件
 * @param content
 * @param ext
 */
export const createTmpFile = (content?: string | object, ext = "json"): FileResult => {
  if (is(Object, content)) content = JSON.stringify(content);
  const tmpFile = tmp.fileSync({ postfix: `.${ext}` });
  if (content) fs.writeFileSync(tmpFile.name, content);
  return tmpFile;
};

/**
 * 计算文件 hash
 * @param path
 */
export const computeHash = async (path: string): Promise<string> => {
  const chunkSize = 1024 * 1024;
  let hash = CryptoJS.algo.SHA256.create();
  const fileStream = fs.createReadStream(path, { highWaterMark: chunkSize });
  return new Promise((resolve, reject) => {
    fileStream.on("data", (chunk) => {
      hash = hash.update(CryptoJS.lib.WordArray.create(chunk as Buffer));
    });
    fileStream.on("end", () => {
      const hashHex = hash.finalize().toString(CryptoJS.enc.Hex);
      resolve(hashHex);
    });
    fileStream.on("error", (err) => {
      reject(err);
    });
  });
};

/**
 * 返回文件后缀
 * @param filename
 */
export const getSuffix = (filename: string) => {
  return filename.split(".").pop();
};
